package com.lonely.fx.task;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * @date: 2022-08-07 12:45
 * @author: ztkj-hzb
 * @description:
 **/
public class ScheduleServiceSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     *
     */
    @Override
    public void start(Stage primaryStage) throws Exception {


        HBox hBox = new HBox();

        Button startBtn = new Button("开始");
        Button cancelBtn = new Button("取消");
        Button resetBtn = new Button("重置");
        Button restartBtn = new Button("重启");

        Label progressLbl = new Label("进度值");
        Label statuLbl = new Label("任务状态");

        hBox.getChildren().addAll(startBtn, cancelBtn, resetBtn, restartBtn, progressLbl, statuLbl);
        hBox.setAlignment(Pos.CENTER);
        hBox.setSpacing(30);
        primaryStage.setScene(new Scene(hBox));
        primaryStage.setWidth(800);
        primaryStage.setHeight(400);
        primaryStage.show();


        MyScheduleService myScheduleService = new MyScheduleService();
        myScheduleService.setDelay(Duration.seconds(3));
        //每次任务的间隔时间
        myScheduleService.setPeriod(Duration.seconds(1));
        //设置异常最多次数.到达指定次数后，任务不再继续执行
        myScheduleService.setMaximumFailureCount(3);
        //设置多少时间间隔内，失败次数达到上限属于不正常
        //myScheduleService.setMaximumCumulativePeriod();
        //任务失败是否自动重启,默认为true
        myScheduleService.setRestartOnFailure(true);
        //myScheduleService.setBackoffStrategy();


        startBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myScheduleService.start();
            }
        });

        cancelBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myScheduleService.cancel();
            }
        });

        resetBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myScheduleService.reset();
            }
        });

        restartBtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                myScheduleService.restart();
            }
        });


        myScheduleService.stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
                statuLbl.setText(newValue.name());
            }
        });

        myScheduleService.lastValueProperty().addListener(new ChangeListener<Integer>() {
            @Override
            public void changed(ObservableValue<? extends Integer> observable, Integer oldValue, Integer newValue) {
                progressLbl.setText(newValue + "");
            }
        });

    }
}


class MyScheduleService extends ScheduledService<Integer> {
    int sum = 0;

    /**
     *
     */
    @Override
    protected Task<Integer> createTask() {

        return new Task<Integer>() {

            @Override
            protected Integer call() throws Exception {
                System.out.println("触发call");
                sum += 1;

                //System.out.println("date:" + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
                //Thread.sleep(2000);

                //System.out.println(1/0);

                return sum;
            }

            /**
             * A protected convenience method for subclasses, called whenever the
             * state of the Task has transitioned to the CANCELLED state.
             * This method is invoked on the FX Application Thread after the Task has been fully transitioned to
             * the new state.
             *
             * @since JavaFX 2.1
             */
            @Override
            protected void cancelled() {
                super.cancelled();
                System.out.println("任务取消了");
            }


            /**
             * A protected convenience method for subclasses, called whenever the
             * state of the Task has transitioned to the FAILED state.
             * This method is invoked on the FX Application Thread after the Task has been fully transitioned to
             * the new state.
             *
             * @since JavaFX 2.1
             */
            @Override
            protected void failed() {
                super.failed();
                System.out.println("任务异常");
            }
        };
    }

    /**
     * @inheritDoc Implementation Note: Subclasses which override this method must call this super implementation.
     */
    @Override
    public void reset() {
        super.reset();
        sum = 0;
    }
}